//
//  Util.swift
//  fir-mac
//
//  Created by isaced on 2017/5/8.
//
//

import Foundation
import Cocoa
import Zip

enum UploadAppIOSReleaseType: String {
    case adhoc = "Adhoc"
    case inHouse = "Inhouse"
}
struct ParsedAppInfo: CustomStringConvertible {
    
    var appName: String?
    var bundleID: String?
    var version: String?
    var build: String?
    var type: UploadAppType?
    var iosReleaseType: UploadAppIOSReleaseType?
    
    var iconImage: NSImage?
    var iconUrl: URL?

    var sourceFileURL: URL?
    
    var description: String {
        return "--- App Info --- \nApp Name: \((appName ?? "")) \nBundle ID: \((bundleID ?? "")) \nVersion: \((version ?? "")) \nBuild: \((build ?? ""))\nType: \(type?.rawValue ?? "")\nIcon: \(iconImage != nil ? "YES":"NO") \n--- App Info ---"
    }
}

class Util {
    
    //MARK: Constants
    fileprivate static let mktempPath = "/usr/bin/mktemp"
    fileprivate static let unzipPath = "/usr/bin/unzip"
    fileprivate static let zipPath = "/usr/bin/zip"
    fileprivate static let defaultsPath = "/usr/bin/defaults"
    
    static func configAppInfo(appUrl: URL, callback:((_ : ParsedAppInfo?)->Void)) {
        if appUrl.pathExtension.lowercased() != "app" {
            let alert = NSAlert()
            alert.messageText = "文件选错了"
            alert.addButton(withTitle: "确定")
            alert.runModal()
            return
        }
        
        let infoPlistPath = appUrl.appendingPathComponent("Info.plist")
        
        if !infoPlistPath.isExists() {
            let alert = NSAlert()
            alert.messageText = "找不到infoPlist文件"
            alert.addButton(withTitle: "确定")
            alert.runModal()
            return
        }
        
        guard let data = try? Data(contentsOf: infoPlistPath) else {
            print("plist解析有问题")
            return
        }
        guard let plist = (try? PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)) as? [String: Any] else {
            print("plist解析有问题")
            return
        }
        
        var info = ParsedAppInfo()
        info.bundleID = plist["CFBundleIdentifier"] as? String
        info.version = plist["CFBundleShortVersionString"] as? String
        info.build = plist["CFBundleVersion"] as? String
        info.appName = (plist["CFBundleDisplayName"] as? String) ?? (plist["CFBundleName"] as? String)
        info.type = .ios
        
        // icon
        let iconNames = ["AppIcon60x60@3x.png",
                         "AppIcon60x60@2x.png",
                         "AppIcon57x57@3x.png",
                         "AppIcon57x57@2x.png",
                         "AppIcon40x40@3x.png",
                         "AppIcon40x40@2x.png"]
        
        for iconName in iconNames {
            let iconFile = appUrl.appendingPathComponent(iconName, isDirectory: false)
            if iconFile.isExists() {
                info.iconImage = NSImage(contentsOfFile: iconFile.path)
                info.iconUrl = iconFile
                break
            }
        }
        
        
        //再创建一个payload的ipa文件
        var upperFolder = appUrl.path
        upperFolder.removeLast(appUrl.lastPathComponent.count + 1)
        let payLoadFolderPath = upperFolder + "/Payload"
        let copyAppPath = payLoadFolderPath + "/" + appUrl.lastPathComponent
        
        createDirectory(path: payLoadFolderPath)
        
        do {
            try FileManager.default.copyItem(atPath: appUrl.path, toPath: copyAppPath)
        } catch {
            print("复制app到payload有问题")
            return
        }
        
        let resultPath = payLoadFolderPath + ".ipa"
        do {
            let zipFilePath = try Zip.quickZipFiles([URL(fileURLWithPath: payLoadFolderPath)], fileName: "Payload")
            
            do {
                try FileManager.default.moveItem(atPath: zipFilePath.path, toPath: resultPath)
            } catch {
                print("移动zip文件有问题")
            }
            let resultUrl = URL(fileURLWithPath: resultPath)
            if resultUrl.isExists() {
                info.sourceFileURL = resultUrl
                callback(info)
                
                do {
                //删除zipFilePath
                    try FileManager.default.removeItem(at: zipFilePath)
                } catch {
                    print("删除zipFilePath有问题")
                }
            } else {
                print("ipa没压缩")
            }
            
        } catch  {
            print("ipa压缩有问题")
        }
        
    
    }
    
    static func createDirectory(path: String) {
        let manager = FileManager.default
        do {
            if manager.fileExists(atPath: path) {
                try manager.removeItem(atPath: path)
            }
            try manager.createDirectory(atPath: path, withIntermediateDirectories: true)
        } catch {
            print("创建 \(path) 文件夹失败")
        }
    }
    
    static func cleanTempDir(path: URL) {
        try! FileManager.default.removeItem(atPath: path.path)
        print("--- clean temp dir...")
    }
    
    static func makeTempFolder() -> URL? {
        let tempTask = Process().execute(mktempPath, workingDirectory: nil, arguments: ["-d"])
        let url = URL(fileURLWithPath: tempTask.output.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines), isDirectory: true)
        return url
    }
    
    static func generateQRCode(from string: String, size: NSSize? = nil) -> NSImage? {
        let data = string.data(using: String.Encoding.ascii)
        
        if let filter = CIFilter(name: "CIQRCodeGenerator") {
            filter.setValue(data, forKey: "inputMessage")
            let transform = CGAffineTransform(scaleX: 3, y: 3)
            
            if let output = filter.outputImage?.transformed(by: transform) {
                let rep = NSCIImageRep(ciImage: output)
                let nsImage = NSImage(size: size ?? rep.size)
                nsImage.addRepresentation(rep)
                return nsImage
            }
        }
        
        return nil
    }
}


extension URL {
    func isExists(dir: Bool = false) -> Bool {
        if dir {
            var isDirectory: ObjCBool = true
            return FileManager.default.fileExists(atPath: self.path, isDirectory: &isDirectory)
        }else{
            return FileManager.default.fileExists(atPath: self.path)
        }
    }
}
